<?php
class Merchant_Service_Plan
{	
	
	protected $_modelPlan = null;
	protected $_modelPlanUsage = null;
	protected $_modelPlanRates = null;
	protected $_modelPlanUsageDetail = null;
	
	//初始化
	public function __construct(){
		$this->_modelPlan = new Merchant_Model_Plan();
		$this->_modelPlan->getDbTable();
		$this->_modelPlanUsage = new Merchant_Model_PlanUsage();
		$this->_modelPlanUsage->getDbTable();
		$this->_modelPlanRates = new Merchant_Model_PlanRates();
		$this->_modelPlanRates->getDbTable();
        $this->_modelPlanUsageDetail = new Merchant_Model_PlanUsageDetail();
        $this->_modelPlanUsageDetail->getDbTable();
	}
	
	
	/**
	 * 创建套餐
	 * @param int customer_id
	 * @param int skus
	 * @param int pallets
	 * @param int items
	 * @return int
	 */
	public function createPlan($customerId, $skus, $pallets, $items){
	
		$total = $this->caculatePlanTotal($skus, $pallets, $items);
		$created = date("Y-m-d H:i:s");
		$plan =  array(
	    		'customer_id' => $customerId,
	    		    'sku_qty' => $skus,
	    		 'pallet_qty' => $pallets,
	    		   'item_qty' => $items,
	    	   'billing_date' => date("j"),
	    		      'total' => $total,
	    		     'active' => 1,
	    		    'created' => $created,
	    		
	    		);
	    
	    $planUsage =  array(
	    		'customer_id' => $customerId,
	    		'sku_qty' => $skus,
	    		'pallet_qty' => $pallets,
	    		'item_qty' => $items,
	    		'billing_date' => date("Ymd"),
	    		// 'total' => $total,
	    		'active' => 1,
	    		'created' => $created,
	    );
	    
	    
	    $dbAdapter = $this->_modelPlan->getDbTable()->getAdapter();
	    $dbAdapter->beginTransaction();
	    try{
	    	 $planId = $this->_modelPlan->getDbTable()->insert($plan);
	    	 if ($planId > 0 ){
	    	 $planUsage['plan_id'] = $planId; 
	    	 $this->_modelPlanUsage->getDbTable()->insert($planUsage);
	    	 $dbAdapter->commit();
	    	 return true;
	    	 }else{
	    	 	return false;
	    	 }
	    	
	    }catch(Exception $e){
			echo $e->getMessage();
	    	$dbAdapter->rollback();
			$logger =  Zend_Registry::get('log');
			$logger->info(date('Y-m-d H:i:s').': '.$e->getMessage()." \n");
	    	return false;
	    }
	}
	
	/**
	*
	*
	*
	*/
	public function getPlanById($planId){
		return $this->_modelPlan->getPlanById($planId);
	}
	
	
	/**
	* 更改套餐
	* @param int customer_id
	* @param int skus
	* @param int pallets
	* @param int items
	* @return int $err_code
	* $err_code 0 => 修改成功
	* $err_code 1 => 修改失败，数据更新出错
	* $err_code 2 => 修改失败，某个用量已经超出目标套餐
	* 
	*/
	public function changePlan($customerId, $skus, $pallets, $items){
		
		$created = date("Y-m-d H:i:s");
		$currentPlan = $this->_modelPlan->getActivePlan($customerId);
		$currentPlanUsage = $this->_modelPlanUsage->getCurrentPlanUsage($customerId);
		if ($currentPlanUsage['sku_used'] <= $skus && $currentPlanUsage['pallet_used'] <= $pallets && $currentPlanUsage['item_used'] <= $items) {
		
			$newTotal = $this->caculatePlanTotal($skus, $pallets, $items);
			$currentUsageTotal = $this->caculatePlanTotal($currentPlanUsage['sku_qty'], $currentPlanUsage['pallet_qty'], $currentPlanUsage['item_qty']);
			if ($currentUsageTotal < $newTotal){//升级套餐
				$newPlan =  array(
						'customer_id' => $customerId,
						'former_planid' => $currentPlan['plan_id'],
						'sku_qty' => $skus,
						'pallet_qty' => $pallets,
						'item_qty' => $items,
						'billing_date' => $currentPlan['billing_date'],
						'total' => $newTotal,
						'upgrade' => 1,
						'active' => 1,
						'created' => $created,
				);
				$newPlanUsage =  array(
						'customer_id' => $customerId,
						'former_pu_id' => $currentPlanUsage['pu_id'],
						'sku_qty' => $skus,
						'pallet_qty' => $pallets,
						'item_qty' => $items,
						'sku_used' => $currentPlanUsage['sku_used'],
						'pallet_used' => $currentPlanUsage['pallet_used'],
						'item_used' => $currentPlanUsage['item_used'],
						'billing_date' => $currentPlanUsage['billing_date'],
						// 'total' => $newTotal,
						'active' => 1,
						'created' => $created,
				);
				
				$dbAdapter = $this->_modelPlan->getDbTable()->getAdapter();
				$dbAdapter->beginTransaction();
				try{
					$newPlanId = $this->_modelPlan->getDbTable()->insert($newPlan);
					if ($newPlanId > 0 ){
						$this->_modelPlan->updatePlanStatus($currentPlan['plan_id']);
						$newPlanUsage['plan_id'] = $newPlanId;
						$newPlanUsageId = $this->_modelPlanUsage->getDbTable()->insert($newPlanUsage);
						if ($newPlanUsageId > 0){
							$this->_modelPlanUsage->updatePlanUsageStatus($currentPlanUsage['pu_id']);
						}
						$dbAdapter->commit();
						$err_code = 0;
					}else{
						$err_code = 1;
					}
				
				}catch(Exception $e){
					echo $e->getTraceAsString();
					echo $e->getMessage();
					$dbAdapter->rollback();
					$logger =  Zend_Registry::get('log');
					$logger->info(date('Y-m-d H:i:s').': '.$e->getMessage()." \n");
					return $err_code;
				}
				
			}else {//降级套餐
				$newPlan =  array(
						'customer_id' => $customerId,
						'former_planid' => $currentPlan['plan_id'],
						'sku_qty' => $skus,
						'pallet_qty' => $pallets,
						'item_qty' => $items,
						'billing_date' => $currentPlan['billing_date'],
						'total' => $newTotal,
						'upgrade' => -1,
						'active' => 1,
						'created' => $created,
				);
				$dbAdapter = $this->_modelPlan->getDbTable()->getAdapter();
				$dbAdapter->beginTransaction();
				try{
					$newPlanId = $this->_modelPlan->getDbTable()->insert($newPlan);
					if ($newPlanId > 0 ){
						$this->_modelPlan->updatePlanStatus($currentPlan['plan_id']);
						$dbAdapter->commit();
						$err_code = 0;
					}else{
						$err_code = 1;
					}
				
				}catch(Exception $e){
					echo $e->getTraceAsString();
					echo $e->getMessage();
					$dbAdapter->rollback();
					$logger =  Zend_Registry::get('log');
					$logger->info(date('Y-m-d H:i:s').': '.$e->getMessage()." \n");
					$err_code = 1;
					return $err_code;
				}
				
			}
		
		}else{
			$err_code = 2;
		}
		
		return $err_code;
	}
	
	
	/**
	 * 回退套餐
	 * @param int customer_id
	 * @return int err_code
	 * err_code 0  回退成功
	 * err_code 1 回退失败，数据操作失败
	 * err_code 2 升级回退失败，已超过24小时
	 * err_code 3 升级回退失败，用量已超过原套餐
	 * 
	 */
	public function rollbackPlan($customer_id){
		$created = date("Y-m-d H:i:s");
		$currentPlan = $this->_modelPlan->getActivePlan($customerId);
		$formerPlan = $this->_modelPlan->getPlanById($currentPlan['former_planid']);
		$currentPlanUsage = $this->_modelPlanUsage->getPlanUsageByCustomerId($customerId);
		if ($currentPlan['upgrade'] == 1){//升级回退
			if ( strtotime('now') - strtotime($currentPlan['created']) < 24*60*60 ){//24小时之内
				//用量是否超过原套餐
				if ($currentPlanUsage['sku_used'] > $formerPlan['sku_qty'] || $currentPlanUsage['pallet_used'] > $formerPlan['pallet_qty'] || $currentPlanUsage['item_used'] > $formerPlan['item_qty']){
					$err_code = 3;
				}else{
					$newPlan =  array(
							'customer_id' => $customerId,
							'former_planid' => $currentPlan['plan_id'],
							'sku_qty' => $formerPlan['sku_qty'],
							'pallet_qty' => $formerPlan['pallet_qty'],
							'item_qty' => $formerPlan['item_qty'],
							'billing_date' => $formerPlan['billing_date'],
							'total' => $formerPlan['total'],
							'upgrade' => 0,
							'active' => 1,
							'created' => $created,
					);
					$newPlanUsage =  array(
							'customer_id' => $customerId,
							'former_pu_id' => $currentPlanUsage['pu_id'],
							'sku_qty' => $formerPlan['sku_qty'],
							'pallet_qty' => $formerPlan['pallet_qty'],
							'item_qty' => $formerPlan['item_qty'],
							'sku_used' => $currentPlanUsage['sku_used'],
							'pallet_used' => $currentPlanUsage['pallet_used'],
							'item_used' => $currentPlanUsage['item_used'],
							'billing_date' => $currentPlanUsage['billing_date'],
							'total' => $formerPlan['total'],
							'active' => 1,
							'created' => $created,
					);
					
					$dbAdapter = $this->_modelPlan->getDbTable()->getAdapter();
					$dbAdapter->beginTransaction();
					try{
						$newPlanId = $this->_modelPlan->getTable()->insert($newPlan);
						if ($newPlanId > 0 ){
							$this->_modelPlan->updatePlanStatus($currentPlan['plan_id']);
							$newPlanUsage['plan_id'] = $newPlanId;
							$newPlanUsageId = $this->_modelPlanUsage->getTable()->insert($newPlanUsage);
							if ($newPlanUsageId > 0){
								$this->_modelPlanUsage->updatePlanUsageStatus($currentPlanUsage['pu_id']);
							}
							$dbAdapter->commit();
							$err_code = 0;
						}else{
							$err_code = 1;
						}
					
					}catch(Exception $e){
						$dbAdapter->rollback();
						$err_code = 1;
					}
				}
			}else{
				$err_code = 2;
			}
		}elseif ($currentPlan['upgrade'] == -1){//降级回退
			
				$newPlan =  array(
						'customer_id' => $customerId,
						'former_planid' => $currentPlan['plan_id'],
						'sku_qty' => $formerPlan['sku_qty'],
						'pallet_qty' => $formerPlan['pallet_qty'],
						'item_qty' => $formerPlan['item_qty'],
						'billing_date' => $formerPlan['billing_date'],
						'total' => $formerPlan['total'],
						'upgrade' => 0,
						'active' => 1,
						'created' => $created,
				);
							
				$dbAdapter = $this->_modelPlan->getDbTable()->getAdapter();
				$dbAdapter->beginTransaction();
				try{
					$newPlanId = $this->_modelPlan->getTable()->insert($newPlan);
					if ($newPlanId > 0 ){
						$this->_modelPlan->updatePlanStatus($currentPlan['plan_id']);
						$dbAdapter->commit();
						$err_code = 0;
					}else{
						$err_code = 1;
					}
			
				}catch(Exception $e){
					$dbAdapter->rollback();
					$logger =  Zend_Registry::get('log');
					$logger->info(date('Y-m-d H:i:s').': '.$e->getMessage()." \n");
					$err_code = 1;
				}
			
			
		}
		return $err_code;
	}
	
	
	/**
	 * 计算套餐价格
	 */
	public function caculatePlanTotal($skus, $pallets, $items, $currency=null){
	    
		$skuSubTotal = $this->caculatePlanByType('sku', $skus,$currency);
		
		$palletSubTotal = $this->caculatePlanByType('pallet', $pallets,$currency);
		$itemSubTotal = $this->caculatePlanByType('item', $items,$currency);
		$total = $skuSubTotal + $palletSubTotal + $itemSubTotal;
		return $total;
	}
	
	
	/**
	 * 按类型计算套餐价格(sku/item/pallet)
	 */
	public function caculatePlanByType($type, $qty ,$currency=null){
		
		$planRates = $this->_modelPlanRates->getRateByTypeAndQty($type,$qty);
		$subTotal = 0;
		$counts = count($planRates);
		if (!empty($planRates)){
			for ($i = 0; $i < $counts - 1; $i++ ){
				$price = ($planRates[$i]['range_end'] - $planRates[$i]['range_start'])*$planRates[$i]['discount']*$planRates[$i]['price'];
				
				if($currency !== null){
					$endPrice = Default_Service_Currency::changeCurrency($price,$planRates[$i]['currency_code'],$currency);
					if($endPrice['ask'] == "Success"){
						$price = $endPrice["value"];
					}
				}
				$subTotal += $price;
			}		
			$price = ($qty - $planRates[$i]['range_start'])*$planRates[$i]['discount']*$planRates[$i]['price'];
			if($currency !== null){
				$endPrice = Default_Service_Currency::changeCurrency($price,$planRates[$i]['currency_code'],$currency);
				if($endPrice['ask'] == "Success"){
					$price = $endPrice["value"];
				}
			}
			$subTotal += $price;
		}
		return $subTotal;
	}
		
	/**
	 * 获取标准价格(sku/item/pallet)
	 */
	
	public function getListPriceByType($type){
	
		$listPrice = $this->_modelPlanRates->getListPriceByType($type);
		return $listPrice;
	}
	
	/**
	 * 每月套餐续费
	 */
	
	public function renewPlan($customerId){
	
     $currentPlan = $this->_modelPlan->getActivePlan($customerId);
     $currentPlanUsage = $this->_modelPlanUsage->getPlanUsageByCustomerId($customerId);
     $newPlanUsage =  array(
	    		'customer_id' => $customerId,
     		    'plan_id' => $currentPlan['plan_id'],
     		    'former_pu_id' => $currentPlanUsage['pu_id'],
	    		'sku_qty' => $currentPlan['sku_qty'],
	    		'pallet_qty' => $currentPlan['pallet_qty'],
	    		'item_qty' => $currentPlan['item_qty'],
     		    'sku_used' => $currentPlanUsage['sku_used'],
     		    'pallet_used' => $currentPlanUsage['pallet_used'],
	    		'billing_date' => date("Ymd"),
	    		'total' => $plan['total'],
	    		'active' => 1,
	    		'created' => date("Y-m-d H:i:s"),
	    );
     $dbAdapter = $this->_modelPlan->getDbTable()->getAdapter();
     $dbAdapter->beginTransaction();
     try{
     	$puId = $this->_modelPlanUsage->getTable()->insert($newPlanUsage);
     	if ($puId > 0 ){
     		$this->_modelPlanUsage->updatePlanUsageStatus($currentPlanUsage['pu_id']);
     		$dbAdapter->commit();
     		return true;
     	}else{
     		return false;
     	}
     
     }catch(Exception $e){
     	$dbAdapter->rollback();
		$logger =  Zend_Registry::get('log');
		$logger->info(date('Y-m-d H:i:s').': '.$e->getMessage()." \n");
     	return false;
     }
     
     
		
	}
	
	/**
	 * 更新套餐使用情况
	 */

    public function updatePlanUsage($customerId,$type,$qty,$refCode=""){
        $plan=$this->_modelPlanUsage->getCurrentPlanUsage($customerId);
        $type = strtolower($type);
        $procType='';
        switch($type){
            case 'sku':
            case 'outofsku':
                $procType='sku';
                break;
            case 'item':
            case 'outofitem':
                $procType='item';
                break;
            case 'pallet':
            case 'outofpallet':
                $procType='pallet';
                break;
            default:
                $procType='';
                break;
        }
        $result = $this->_modelPlanUsage->updatePlanUsage($customerId,$type,$qty);
        if($result && $procType!=''){
            $planUsageDetail = array(
                'customer_id'=>$customerId,
                'pu_id' =>$plan['pu_id'],
                'type'=>$procType,
                'ref_id'=>$refCode,
                'count'=>	$qty,
                'current_count'=>0,
                'created'=>date('Y-m-d H:i:s')
            );
            $this->_modelPlanUsageDetail->add($planUsageDetail);
        }
        return $result;
    }
	
	/**
	 * 获取当前套餐使用情况
	 */
	
	public function getCurrentPlanUsage($customerId){
	
		$planUsage = $this->_modelPlanUsage->getCurrentPlanUsage($customerId);
		return $planUsage;
	
	}
	
	/**
	 * 获取当前套餐
	 */
	
	public function getCurrentPlan($customerId){
	
		$plan = $this->_modelPlan->getActivePlan($customerId);
		if($plan instanceof Zend_Db_Table_Row){
			return $plan->toArray();
		}
		return $plan;
	}
	
	/**
	 * 获取所有当天结算的套餐
	 */
	
	public function getAllPlansForBillinig(){
	
		$plans = $this->_modelPlan->getAllPlansForBillinig();
		return $plans;
	
	}
	
	/**
	 * 套餐使用详情
	 */
	
	public function insertPlanUsageDetail($row){
	
		return $this->_modelPlanUsageDetail->getTable()->insert($row);
	
	}
	/**
	 * 获取费率数据.
	 */
	public function getRateByTypeAndQty($type,$qty){
		return $this->_modelPlanRates->getRateByTypeAndQty($type,$qty)->toArray();
	}
	
	/*
	*扣除panl usage 操作
	*@param $customerId:用户ID,$procType:处理类型,$qty:数量,$useType：处理来源类型,$refCode:参考订单/item/ASN CODE
	*return array('ask'=>'处理状态','message'=>'处理结果信息','data'=>array('qty'=>末处理数量,'proQty'=>'已处理数量'));
	*
	*/
	public function planProccessing($customerId,$procType='item',$qty=0,$refCode=""){
		 
	 
		$result['ask'] = 'Success';
		$result['data'] = array('item'=>0,'sku'=>0,'pallet'=>0,
								'item_cut'=>0,'sku_cut'=>0,'pallet_cut'=>0);
		$this->_modelPlanUsage->getDbTable();
			$plan = $this->_modelPlanUsage->lockCurrentPlan($customerId);
			
			$updateRow = array('pallet_used'=>$plan['pallet_used'],'sku_used'=>$plan['sku_used'],'item_used'=>$plan['item_used']);
			if(!is_array($plan)){	
				$result['ask'] = 'Failure';
				//$result['data'] = array('item'=>$item,'sku'=>$sku,'pallet_used'=>$pallet);
				$result['message'] = 'No current plan.';	
				$this->_modelPlanUsage->update($plan['pu_id'],$updateRow);//更新解锁	
				return $result;
			}
			$usageObj = new Merchant_Model_PlanUsageDetail();
			$usageObj->getDbTable();
			
			

			
			$isDo = false;//判断是否有更新
			
			$procType = strtolower($procType);
			 
			$newItem = 0;
			
			switch($procType){
				case 'item':
					$newItem = $plan['item_qty']+$plan['item_add_qty']-$plan['item_used']-$qty;
					if($newItem >= 0){
						 
						$result['data']['qty'] = 0;
						$result['data']['proQty'] = $qty;
						$updateRow['item_used'] = $plan['item_used']+$qty;
						$isDo = true;
					}else{
						$result['ask'] = 'Failure';
						$itemCut = $plan['item_qty']+$plan['item_add_qty']-$plan['item_used'];					 
						$result['data']['qty'] = $qty-$itemCut;
						$result['data']['proQty'] = $itemCut;	
					}
					break;
				case 'sku':
					$newSku = $plan['sku_qty']+$plan['sku_add_qty']-$plan['sku_used']-$qty;
					if($newSku >= 0){
						
						$skuCut = $qty;
						$result['data']['qty'] = 0;
						$result['data']['proQty'] = $qty;
						
						$updateRow['sku_used'] = $plan['sku_used']+$qty;
						$isDo = true;
						 
					}else{
						$result['ask'] = 'Failure';
						$skuCut = $plan['sku_qty']+$plan['sku_add_qty']-$plan['sku_used'];
						//$newSku =0;//更新剩余数量 
						$result['data']['qty'] = $qty-$skuCut;
						$result['data']['proQty'] = $skuCut;	
					}
					break;
				case 'pallet':
					$newPlant = $plan['pallet_qty']+$plan['pallet_add_qty']-$plan['pallet_used']-$qty;
					if($newPlant >= 0){
						$plantCut = $qty;
						$result['data']['qty'] = 0;
						$result['data']['proQty'] = $qty;
						$updateRow['pallet_used'] = $plan['pallet_used']+$qty;
						$isDo = true;
						 
					}else{
						$result['ask'] = 'Failure';
						$skuCut = $plan['pallet_qty']+$plan['pallet_add_qty']-$plan['pallet_used'];
						//$newSku =0;//更新剩余数量 
						$result['data']['qty'] = $qty-$plantCut;
						$result['data']['proQty'] = $plantCut;	
					}
					break;	 
				default:
					$isDo = false;
					break;
			} 
			
			if($isDo){
				$planUsageDetail = array('customer_id'=>$customerId,
										 'pu_id' =>$plan['pu_id'],
										 'type'=>$procType,										 
										 'ref_id'=>$refCode,
										 'count'=>	$qty,
										 'current_count'=>$newItem,
										 'created'=>date('Y-m-d H:i:s')					
										 );
							
						$usageObj->add($planUsageDetail);//添加日志
//						print_r($planUsageDetail);
			}
			$updateRow['last_update'] = date('Y-m-d H:i:s');			
			$this->_modelPlanUsage->update($plan['pu_id'],$updateRow);//unlock 并更新数量	
			 
			return 	$result;
					 
		 		
	}
	
	/**
	 * 获取超出外收费
	 */
	public function getAddtionRate($type,$qty){		 
		 
		$currentRate = $this->_modelPlanRates->getListPriceByType($type);//取回标准费率
		
		$result['value'] = sprintf("%.2f",$currentRate->price)*$qty;// 取小数后两位

		$result['currency_code'] =  $currentRate->currency_code;
	
		return $result;
	}
	/**
	*获取客户Plan使用记录
	*
	*/
	public function getPlanUsageList($condition,$type='*',$orderby="expired desc",$page=0,$pageSize=0){
		return $this->_modelPlanUsage->getByCondition($condition,$type,$orderby,$page,$pageSize);
	}
}